/**
 * ipassbook 0.6.0
 * Copyright (C)2009 wateray and contributors
 * wateray@gmail.com
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

package com.wateray.ipassbook.kernel.service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;

import com.ibatis.dao.client.DaoManager;
import com.wateray.ipassbook.ApplicationConfig;
import com.wateray.ipassbook.commom.CommomTool;
import com.wateray.ipassbook.domain.Currency;
import com.wateray.ipassbook.domain.PassbookDetail;
import com.wateray.ipassbook.domain.PassbookTrade;
import com.wateray.ipassbook.domain.form.PassbookTradeForm;
import com.wateray.ipassbook.kernel.event.IPassbookEvent;
import com.wateray.ipassbook.kernel.event.IPassbookEventType;
import com.wateray.ipassbook.kernel.event.IPassbookObserver;
import com.wateray.ipassbook.persistence.DaoConfig;
import com.wateray.ipassbook.persistence.iface.CurrencyDao;
import com.wateray.ipassbook.persistence.iface.PassbookDao;
import com.wateray.ipassbook.persistence.iface.PassbookTradeDao;
import com.wateray.ipassbook.util.log4j.Log;

/**
 * @author wateray
 * @create 2009-5-25
 */
public class PassbookTradeService {
	private PassbookTradeDao passbookTradeDao;
	private PassbookService passbookService;
	private DaoManager daoMgr;
	private Logger logger = Log.getLogger(this.getClass());

	public PassbookTradeService() {
		daoMgr = DaoConfig.getDaoManager();
		this.passbookTradeDao = (PassbookTradeDao) daoMgr
				.getDao(PassbookTradeDao.class);
		passbookService = new PassbookService();
	}

	public PassbookTradeService(DaoManager daoMgr,
			PassbookTradeDao passbookTradeDao) {
		this.daoMgr = daoMgr;
		this.passbookTradeDao = passbookTradeDao;
		passbookService = new PassbookService();
	}

	public PassbookTradeForm getPassbookTradeFormById(String tradeId) {
		Map<String, String> map = new HashMap<String, String>();
		map.put("languageId", ApplicationConfig.getLang());
		map.put("tradeId", tradeId);

		return passbookTradeDao.getPassbookTradeFormById(map);
	}

	public List<PassbookTradeForm> getPassbookTradeFormList(String beginDay,
			String endDay) {
		Map<String, String> map = new HashMap<String, String>();
//		map.put("languageId", ApplicationConfig.getLang());
		map.put("languageId", "001");
		map.put("beginDay", beginDay);
		map.put("endDay", endDay);

		return passbookTradeDao.getPassbookTradeFormList(map);
	}
	
	public String insertPassbookTrade(PassbookTrade trade) {
		String tradeId = "";
		try {
			daoMgr.startTransaction();
			// tradeId
			tradeId = passbookTradeDao.getPassbookTradeMaxId();
			tradeId = CommomTool.plusOneFillZero(tradeId, 10);
			trade.setTradeId(tradeId);
			
			PassbookDetail out,  in;
			out = passbookService.getPassbookDetailById(trade.getOutPassbookId(), trade.getOutPassbookSubId());
			in = passbookService.getPassbookDetailById(trade.getInPassbookId(), trade.getInPassbookSubId());
			double outBanlance = out.getBalance() - trade.getOutAmount();
			double inBanlance = in.getBalance() + trade.getInAmount();
			
			//update balance
			out.setBalance(outBanlance);
			in.setBalance(inBanlance);
			
			//insert trade.
			passbookTradeDao.insertPassbookTrade(trade);
			
			passbookService.updatePassbookDetailBalance(out);
			passbookService.updatePassbookDetailBalance(in);
			
			daoMgr.commitTransaction();
			
			// invoke Events
			IPassbookObserver.getInstance().notifyEvents(
					new IPassbookEvent(this,
							IPassbookEventType.PassbookTableModifyEvent));
			
		} finally {
			daoMgr.endTransaction();
		}
		return tradeId;
	}
	
	/**
	 * @param trade -- PassbookTrade.
	 * */
	public void updatePassbookTrade(PassbookTrade trade) {
		/**!!important!!*/
		/**inPassbook, outPassbook don't allowed to change.
		 * If it is need to change them. 
		 * First deletePassbookTrade, then insertPassbookTrade. 
		 *  */	
		
		PassbookTrade oldTrade;
		PassbookDetail out,  in;
		
		try {
			daoMgr.startTransaction();

			oldTrade = getPassbookTradeFormById(trade.getTradeId());
			
			//inPassbook, outPassbook  have been changed.
			if(!oldTrade.getOutPassbookDetailId().equals(trade.getOutPassbookDetailId())
					||!oldTrade.getInPassbookDetailId().equals(trade.getInPassbookDetailId())){
//				//deletePassbookTrade old trade.
//				deletePassbookTrade(oldTrade);
//				
//				//insert new trade.
//				insertPassbookTrade(trade);
				logger.error(" updatePassbookTrade: inPassbook, outPassbook don't allowed to change.");
				return;
				
			}
			//end.
			
			out = passbookService.getPassbookDetailById(trade.getOutPassbookId(), trade.getOutPassbookSubId());
			in = passbookService.getPassbookDetailById(trade.getInPassbookId(), trade.getInPassbookSubId());
			double diffOutAmount = oldTrade.getOutAmount() -  trade.getOutAmount();
			double diffInAmount = oldTrade.getInAmount() - trade.getInAmount();
			double outBanlance = out.getBalance() + diffOutAmount;
			double inBanlance = in.getBalance() - diffInAmount;
			
			//update balance
			out.setBalance(outBanlance);
			in.setBalance(inBanlance);
			
			//update trade.
			passbookTradeDao.updatePassbookTrade(trade);
			
			passbookService.updatePassbookDetailBalance(out);
			passbookService.updatePassbookDetailBalance(in);
			
			daoMgr.commitTransaction();
			
			// invoke Events
			IPassbookObserver.getInstance().notifyEvents(
					new IPassbookEvent(this,
							IPassbookEventType.PassbookTableModifyEvent));
			
		} finally {
			daoMgr.endTransaction();
		}	
	}
	
	public void deletePassbookTrade(PassbookTrade trade) {
		
		try {
			daoMgr.startTransaction();
			
			PassbookTrade oldTrade = getPassbookTradeFormById(trade.getTradeId());
		
			PassbookDetail out,  in;
			out = passbookService.getPassbookDetailById(oldTrade.getOutPassbookId(), oldTrade.getOutPassbookSubId());
			in = passbookService.getPassbookDetailById(oldTrade.getInPassbookId(), oldTrade.getInPassbookSubId());

			double outBanlance = out.getBalance() + oldTrade.getOutAmount();
			double inBanlance = in.getBalance() - oldTrade.getInAmount();
			
			//update balance
			out.setBalance(outBanlance);
			in.setBalance(inBanlance);
			
			//delete trade.
			passbookTradeDao.deletePassbookTrade(oldTrade);
			
			passbookService.updatePassbookDetailBalance(out);
			passbookService.updatePassbookDetailBalance(in);
			
			daoMgr.commitTransaction();
			
			// invoke Events
			IPassbookObserver.getInstance().notifyEvents(
					new IPassbookEvent(this,
							IPassbookEventType.PassbookTableModifyEvent));
			
		} finally {
			daoMgr.endTransaction();
		}	
	}
	
	public static void main(String[] args) {
		PassbookTradeService service = new PassbookTradeService();
		service.getPassbookTradeFormList("2009-01-01", "2009-09-09");
	}
}
